﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.IO;
using System.Windows.Threading;
using System.Threading;
using System.Data;
using System.Xml.Serialization;

namespace MediaPlayer_Beta
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    ///         


    public partial class MainWindow : Window
    {
        Librairie libra;

        DispatcherTimer timer;

        public delegate void timerTick();
        timerTick tick;

        bool isDragging = false;
        bool fileIsPlaying = false;
        string sec, min, hours, Ext;

      public List<Ressource> LectList;
      public List<playlist> playlists;

        public MainWindow()
        {
            LectList = new List<Ressource>();
            InitializeComponent();
            libra = new Librairie();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += new EventHandler(timer_Tick);
            tick = new timerTick(changeStatus);
            XmlSerializer x = new XmlSerializer(typeof(List<playlist>));
            try
            {
                using (StreamReader rd = new StreamReader("Playlist.xml"))
                {
                    playlists = x.Deserialize(rd) as List<playlist>;
                }
            }
            catch (Exception)
            {
                playlists = new List<playlist>();
            }
        }

        void timer_Tick(object sender, EventArgs e)
        {
            Dispatcher.Invoke(tick);
        }

        void changeStatus()
        {
            if (fileIsPlaying)
            {

                #region customizeTime
                if (mediaElement.Position.Seconds < 10)
                    sec = "0" + mediaElement.Position.Seconds.ToString();
                else
                    sec = mediaElement.Position.Seconds.ToString();


                if (mediaElement.Position.Minutes < 10)
                    min = "0" + mediaElement.Position.Minutes.ToString();
                else
                    min = mediaElement.Position.Minutes.ToString();

                if (mediaElement.Position.Hours < 10)
                    hours = "0" + mediaElement.Position.Hours.ToString();
                else
                    hours = mediaElement.Position.Hours.ToString();

                #endregion customizeTime

                seekSlider.Value = mediaElement.Position.TotalMilliseconds;
                progressBar.Value = mediaElement.Position.TotalMilliseconds;

                if (mediaElement.Position.Hours == 0)
                {

                    currentTimeTextBlock.Text = min + ":" + sec;
                }
                else
                {
                    currentTimeTextBlock.Text = hours + ":" + min + ":" + sec;
                }
            }
        }

        private void playlist_Save(object sender, RoutedEventArgs e)
        {
            Window name = new NamePlaylistControler(this.LectList, playlists);
            name.ShowDialog();
        }

        private void openPL(object sender, RoutedEventArgs e)
        {
            Window menu = new Window1(LectList, playlists, ListParam);
            menu.ShowDialog();
            
        }

        private void openFileButton_Click(object sender, RoutedEventArgs e)
        {
            Stream checkStream = null;
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Supported File Types(*.mp3,*.wav,*.mpeg,*.wmv,*.avi;*.jpg;*.png)|*.mp3;*.wav;*.mpeg;*.wmv;*.avi;*.jpg;*.png";

            if ((bool)dlg.ShowDialog())
            {

                if ((checkStream = dlg.OpenFile()) != null)
                {

                    String exten = System.IO.Path.GetExtension(dlg.FileName);
                    if (exten.Equals(".mpeg") || exten.Equals(".wmv") || exten.Equals(".avi"))
                    {
                        Vide vid = new Vide();
                        vid.id = libra.id_max++;
                        vid.path = dlg.FileName;
                        vid.name = System.IO.Path.GetFileName(dlg.FileName);
                         bool pres = false;
                        foreach (Vide elem in libra.lib)
                        {
                            if (elem.path.Equals(vid.path))
                                pres = true;
                        }
                        if (!pres)
                        {
                            libra.lib.Add(vid);
                            XmlSerializer xs = new XmlSerializer(typeof(List<Vide>));
                            using (StreamWriter wr = new StreamWriter("Videos.xml"))
                            {
                                xs.Serialize(wr, libra.lib);
                            }
                        }
                    }
                    else if (exten.Equals(".mp3") || exten.Equals(".wav"))
                    {
                        Musique vid = new Musique();
                        vid.id = libra.id_max++;
                        vid.path = dlg.FileName;
                        TagLib.File f = TagLib.File.Create(dlg.FileName);
                        vid.Artiste = f.Tag.FirstPerformer;
                        vid.Album = f.Tag.Album;
                        vid.Genre = f.Tag.FirstGenre;
                        vid.name = System.IO.Path.GetFileName(dlg.FileName);
                        bool pres = false;
                        foreach (Musique elem in libra.Muse)
                        {
                            if (elem.path.Equals(vid.path))
                                pres = true;
                        }
                        if (!pres)
                        {
                            libra.Muse.Add(vid);
                            XmlSerializer xs = new XmlSerializer(typeof(List<Musique>));
                            using (StreamWriter wr = new StreamWriter("Musiques.xml"))
                            {
                                xs.Serialize(wr, libra.Muse);
                            }
                        }
                    }
                    else
                    {
                        Img vid = new Img();
                        vid.id = libra.id_max++;
                        vid.path = dlg.FileName;
                        vid.name = System.IO.Path.GetFileName(dlg.FileName);
                         bool pres = false;
                        foreach (Img elem in libra.Ims)
                        {
                            if (elem.path.Equals(vid.path))
                                pres = true;
                        }
                        if (!pres)
                        {
                            libra.Ims.Add(vid);
                            XmlSerializer xs = new XmlSerializer(typeof(List<Img>));
                            using (StreamWriter wr = new StreamWriter("Image.xml"))
                            {
                                xs.Serialize(wr, libra.Ims);
                            }
                        }
                    }

                    Ressource ress = new Ressource();
                    ress.name = System.IO.Path.GetFileName(dlg.FileName);
                    ress.path = dlg.FileName;
                    LectList.Add(ress);
                    ListParam.Items.Add(System.IO.Path.GetFileName(dlg.FileName));
                    }
                }
            }



        public void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
        {
            if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
            {
                timer.Start();
            }
            fileIsPlaying = true;
            openMedia();
        }

        public void openMedia()
        {
            InitializePropertyValues();
            try
            {
                Ext = System.IO.Path.GetExtension((String)ListParam.SelectedItems[0]);
                if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
                {
                    #region customizeTime

                    if (mediaElement.NaturalDuration.TimeSpan.Seconds < 10)
                        sec = "0" + mediaElement.Position.Seconds.ToString();
                    else
                        sec = mediaElement.NaturalDuration.TimeSpan.Seconds.ToString();

                    if (mediaElement.NaturalDuration.TimeSpan.Minutes < 10)
                        min = "0" + mediaElement.NaturalDuration.TimeSpan.Minutes.ToString();
                    else
                        min = mediaElement.NaturalDuration.TimeSpan.Minutes.ToString();

                    if (mediaElement.NaturalDuration.TimeSpan.Hours < 10)
                        hours = "0" + mediaElement.NaturalDuration.TimeSpan.Hours.ToString();
                    else
                        hours = mediaElement.NaturalDuration.TimeSpan.Hours.ToString();

                    if (mediaElement.NaturalDuration.TimeSpan.Hours == 0)
                    {

                        endTimeTextBlock.Text = min + ":" + sec;
                    }
                    else
                    {
                        endTimeTextBlock.Text = hours + ":" + min + ":" + sec;
                    }

                    #endregion customizeTime
                }
            }
            catch
            {
            }
            string path = mediaElement.Source.LocalPath.ToString();

            if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
            {
                double duration = mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds;
                seekSlider.Maximum = duration;
                progressBar.Maximum = duration;

                mediaElement.Volume = volumeSlider.Value;
                mediaElement.SpeedRatio = speedRatioSlider.Value;
                mediaElement.ScrubbingEnabled = true;

                volumeSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(volumeSlider_ValueChanged);
                speedRatioSlider.ValueChanged +=
                    new RoutedPropertyChangedEventHandler<double>(speedRatioSlider_ValueChanged);
            }
        }

        private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
            {
                mediaElement.Stop();
                ListParam.SelectedIndex = ListParam.SelectedIndex + 1;
                volumeSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(volumeSlider_ValueChanged);
                speedRatioSlider.ValueChanged -=
                    new RoutedPropertyChangedEventHandler<double>(speedRatioSlider_ValueChanged);
            }
        }

        private void next_Elem(object sender, RoutedEventArgs e)
        {
            mediaElement.Stop();
            mediaElement.Stop();
            if (ListParam.SelectedIndex != -1)
            ListParam.SelectedIndex = ListParam.SelectedIndex + 1;
            volumeSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(volumeSlider_ValueChanged);
            speedRatioSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(speedRatioSlider_ValueChanged);
        }

        private void previous_Elem(object sender, RoutedEventArgs e)
        {
            mediaElement.Stop();
            if (ListParam.SelectedIndex != -1)
                ListParam.SelectedIndex = ListParam.SelectedIndex - 1;
            volumeSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(volumeSlider_ValueChanged);
            speedRatioSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(speedRatioSlider_ValueChanged);
        }


        void InitializePropertyValues()
        {
            mediaElement.Volume = (double)volumeSlider.Value;
            mediaElement.SpeedRatio = (double)speedRatioSlider.Value;
        }


        private void seekSlider_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)seekSlider.Value);

            changePostion(ts);
        }


        private void seekSlider_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isDragging = true;
            fileIsPlaying = false;
        }

        private void seekSlider_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (isDragging)
            {
                TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)seekSlider.Value);
                changePostion(ts);
                fileIsPlaying = true;
            }
            isDragging = false;
        }

        void changePostion(TimeSpan ts)
        {
            mediaElement.Position = ts;
        }

        void speedRatioSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            mediaElement.SpeedRatio = speedRatioSlider.Value;
        }

        private void playButton__Click(object sender, RoutedEventArgs e)
        {
            if (ListParam.Items.Count >= 1)
            {
                if (ListParam.SelectedIndex == -1 && ListParam.Items.Count > 0)
                    ListParam.SelectedIndex = 0;
                if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
                {
                    fileIsPlaying = true;
                    mediaElement.Play();
                    timer.Start();
                }
            }
        }

        private void pauseButton_Click(object sender, RoutedEventArgs e)
        {
            if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
            {
                fileIsPlaying = false;
                mediaElement.Pause();
                timer.Stop();
            }
        }

        private void stopButton_Click(object sender, RoutedEventArgs e)
        {
            if (Ext != ".jpg" && Ext != ".png" && Ext != ".JPG" && Ext != ".PNG")
            {
                fileIsPlaying = false;
                timer.Stop();
                mediaElement.Stop();
                seekSlider.Value = 0;
                progressBar.Value = 0;
                currentTimeTextBlock.Text = "00:00";
            }
        }

        private void volumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
                mediaElement.Volume = volumeSlider.Value;
        }


        private void seekSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {

        }

        private void ListParam_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (ListParam.SelectedIndex != -1)
            {
                try
                {
                    if (LectList[ListParam.SelectedIndex].path != null)
                    {
                        mediaElement.Close();
                        mediaElement.Source = new Uri(LectList[ListParam.SelectedIndex].path);
                        Thread.Sleep(50);
                        mediaElement.Play();
                        fileIsPlaying = true;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. " + ex.Message);
                }
            }
        }

        private void seekSlider_ValueChanged_1(object sender, RoutedPropertyChangedEventArgs<double> e)
        {

        }

        private void ListParam_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                int index = ListParam.SelectedIndex;
                ListParam.Items.RemoveAt(index);
                LectList.RemoveAt(index);
                mediaElement.Close();
                fileIsPlaying = false;
            }
        }
        
        private void libraryButton__Click(object sender, RoutedEventArgs e)
        {
            Window libr = new Library(libra, ListParam, LectList);
            libr.ShowDialog();
        }
    }
}